<template>
  <div class="execution-detail-page">
    <div class="page-container">
      <div class="page-header">
        <h2 class="page-title">执行记录详情</h2>
        <div class="header-actions">
          <el-button @click="$router.back()">返回</el-button>
          <el-button @click="refreshDetail">
            <el-icon><Refresh /></el-icon>
            刷新
          </el-button>
        </div>
      </div>

      <div v-if="loading" class="loading-container">
        <el-skeleton :rows="10" animated />
      </div>

      <template v-else-if="executionDetail">
        <!-- 执行状态概览 -->
        <el-card class="status-overview">
          <div class="status-header">
            <h3>执行状态</h3>
            <el-tag :type="getStatusType(executionDetail.status)" size="large">
              {{ getStatusText(executionDetail.status) }}
            </el-tag>
          </div>

          <el-descriptions :column="3" border>
            <el-descriptions-item label="执行ID">
              {{ executionDetail.id }}
            </el-descriptions-item>
            <el-descriptions-item label="任务名称">
              {{ executionDetail.task_name || '-' }}
            </el-descriptions-item>
            <el-descriptions-item label="触发方式">
              {{ getTriggerTypeText(executionDetail.triggered_by) }}
            </el-descriptions-item>
            <el-descriptions-item label="开始时间">
              {{ formatDateTime(executionDetail.start_time) }}
            </el-descriptions-item>
            <el-descriptions-item label="结束时间">
              {{ formatDateTime(executionDetail.end_time) }}
            </el-descriptions-item>
            <el-descriptions-item label="执行时长">
              {{ formatDuration(executionDetail.duration) }}
            </el-descriptions-item>
            <el-descriptions-item label="源提交">
              <code>{{ executionDetail.source_commit || '-' }}</code>
            </el-descriptions-item>
            <el-descriptions-item label="成功数量" :span="2">
              {{ getSuccessCount() }} / {{ getTotalCount() }}
            </el-descriptions-item>
          </el-descriptions>

          <div v-if="executionDetail.error_message" class="error-message">
            <el-alert
              title="错误信息"
              type="error"
              :description="executionDetail.error_message"
              show-icon
              :closable="false"
            />
          </div>
        </el-card>

        <!-- 操作按钮 -->
        <el-card class="action-card">
          <div class="action-buttons">
            <el-button
              v-if="executionDetail.status === 'failed'"
              type="warning"
              @click="retryExecution"
              :loading="actionLoading.retry"
            >
              <el-icon><RefreshRight /></el-icon>
              重新执行
            </el-button>

            <el-button
              v-if="canRollback"
              type="danger"
              @click="rollbackExecution"
              :loading="actionLoading.rollback"
            >
              <el-icon><RefreshLeft /></el-icon>
              回滚执行
            </el-button>

            <el-button
              @click="verifyExecution"
              :loading="actionLoading.verify"
            >
              <el-icon><Check /></el-icon>
              验证结果
            </el-button>

            <el-button @click="exportLogs">
              <el-icon><Download /></el-icon>
              导出日志
            </el-button>
          </div>
        </el-card>

        <!-- 目标仓库执行结果 -->
        <el-card class="results-card">
          <template #header>
            <div class="card-header">
              <span>目标仓库执行结果</span>
              <el-tag type="info">
                {{ getSuccessCount() }} 成功 / {{ getFailureCount() }} 失败
              </el-tag>
            </div>
          </template>

          <el-table :data="executionDetail.target_results" stripe>
            <el-table-column prop="repo_name" label="仓库名称" />
            <el-table-column prop="repo_url" label="仓库地址" show-overflow-tooltip />
            <el-table-column prop="branch" label="目标分支" width="120" />
            <el-table-column prop="status" label="状态" width="100">
              <template #default="scope">
                <el-tag :type="getStatusType(scope.row.status)">
                  {{ getStatusText(scope.row.status) }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="commit_id" label="提交ID" width="240">
              <template #default="scope">
                <code v-if="scope.row.commit_id">{{ scope.row.commit_id }}</code>
                <span v-else>-</span>
              </template>
            </el-table-column>
            <el-table-column prop="message" label="消息" show-overflow-tooltip />
            <el-table-column prop="duration" label="耗时" width="100">
              <template #default="scope">
                {{ formatDuration(scope.row.duration) }}
              </template>
            </el-table-column>
          </el-table>
        </el-card>

        <!-- 验证结果 -->
        <el-card v-if="executionDetail.verification_results" class="verification-card">
          <template #header>
            <div class="card-header">
              <span>验证结果</span>
              <el-tag type="success">
                {{ getVerificationSuccessCount() }} 通过 / {{ getVerificationFailureCount() }} 失败
              </el-tag>
            </div>
          </template>

          <el-table :data="executionDetail.verification_results" stripe>
            <el-table-column prop="repo_name" label="仓库名称" />
            <el-table-column prop="verification_type" label="验证类型" width="120" />
            <el-table-column prop="status" label="状态" width="100">
              <template #default="scope">
                <el-tag :type="scope.row.status === 'success' ? 'success' : 'danger'">
                  {{ scope.row.status === 'success' ? '通过' : '失败' }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="message" label="验证消息" show-overflow-tooltip />
            <el-table-column prop="verified_at" label="验证时间" width="180">
              <template #default="scope">
                {{ formatDateTime(scope.row.verified_at) }}
              </template>
            </el-table-column>
          </el-table>
        </el-card>

        <!-- 执行日志 -->
        <el-card class="logs-card">
          <template #header>
            <div class="card-header">
              <span>执行日志</span>
              <div class="log-filters">
                <el-select
                  v-model="logFilter.level"
                  placeholder="日志级别"
                  size="small"
                  @change="fetchLogs"
                  clearable
                >
                  <el-option label="全部" value="" />
                  <el-option label="INFO" value="info" />
                  <el-option label="WARNING" value="warning" />
                  <el-option label="ERROR" value="error" />
                </el-select>
                <el-button size="small" @click="fetchLogs">
                  <el-icon><Refresh /></el-icon>
                </el-button>
              </div>
            </div>
          </template>

          <div class="logs-container">
            <div
              v-for="log in logs"
              :key="log.id"
              class="log-item"
              :class="`log-${log.level}`"
            >
              <div class="log-header">
                <span class="log-time">{{ formatDateTime(log.created_at) }}</span>
                <el-tag :type="getLogLevelType(log.level)" size="small">
                  {{ log.level.toUpperCase() }}
                </el-tag>
                <span class="log-step">{{ log.step || '-' }}</span>
              </div>
              <div class="log-message">{{ log.message }}</div>
              <div v-if="log.details" class="log-details">
                <el-collapse>
                  <el-collapse-item title="详细信息">
                    <pre>{{ JSON.stringify(log.details, null, 2) }}</pre>
                  </el-collapse-item>
                </el-collapse>
              </div>
            </div>

            <div v-if="logs.length === 0" class="empty-logs">
              暂无日志记录
            </div>
          </div>

          <!-- 日志分页 -->
          <div v-if="logsTotal > 0" class="logs-pagination">
            <el-pagination
              v-model:current-page="logPagination.page"
              v-model:page-size="logPagination.size"
              :total="logsTotal"
              :page-sizes="[20, 50, 100]"
              layout="total, sizes, prev, pager, next"
              @size-change="fetchLogs"
              @current-change="fetchLogs"
            />
          </div>
        </el-card>
      </template>

      <div v-else class="empty-state">
        <el-icon class="icon" size="48"><DocumentRemove /></el-icon>
        <div class="text">执行记录不存在</div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import {
  Refresh,
  RefreshRight,
  RefreshLeft,
  Check,
  Download,
  DocumentRemove
} from '@element-plus/icons-vue'
import { executionApi, logApi } from '../api'

const router = useRouter()
const route = useRoute()

// 获取执行记录ID
const executionId = computed(() => parseInt(route.params.id))

// 数据状态
const loading = ref(false)
const executionDetail = ref(null)
const logs = ref([])
const logsTotal = ref(0)
const canRollback = ref(false)

// 操作状态
const actionLoading = reactive({
  retry: false,
  rollback: false,
  verify: false
})

// 日志过滤器
const logFilter = reactive({
  level: ''
})

// 日志分页
const logPagination = reactive({
  page: 1,
  size: 50
})

// 获取执行记录详情
const fetchExecutionDetail = async () => {
  if (!executionId.value) return

  loading.value = true
  try {
    const response = await executionApi.getExecution(executionId.value)
    executionDetail.value = response.data

    // 检查是否可以回滚
    if (executionDetail.value.status === 'success' || executionDetail.value.status === 'partial_failure') {
      checkCanRollback()
    }
  } catch (error) {
    console.error('获取执行记录详情失败:', error)
    ElMessage.error('获取执行记录详情失败')
  } finally {
    loading.value = false
  }
}

// 获取执行日志
const fetchLogs = async () => {
  if (!executionId.value) return

  try {
    const params = {
      page: logPagination.page,
      size: logPagination.size,
      level: logFilter.level || undefined
    }

    const response = await executionApi.getExecutionLogs(executionId.value, params)
    logs.value = response.data?.items || []
    logsTotal.value = response.data?.total || 0
  } catch (error) {
    console.error('获取执行日志失败:', error)
    ElMessage.error('获取执行日志失败')
  }
}

// 检查是否可以回滚
const checkCanRollback = async () => {
  try {
    const response = await executionApi.checkCanRollback(executionId.value)
    canRollback.value = response.data?.can_rollback || false
  } catch (error) {
    console.error('检查回滚条件失败:', error)
  }
}

// 刷新详情
const refreshDetail = () => {
  fetchExecutionDetail()
  fetchLogs()
}

// 重新执行
const retryExecution = async () => {
  try {
    await ElMessageBox.confirm(
      '确定要重新执行这个任务吗？',
      '确认重新执行',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )

    actionLoading.retry = true
    await executionApi.retryExecution(executionId.value)
    ElMessage.success('重新执行任务已提交')
    refreshDetail()
  } catch (error) {
    if (error !== 'cancel') {
      console.error('重新执行失败:', error)
      ElMessage.error('重新执行失败')
    }
  } finally {
    actionLoading.retry = false
  }
}

// 回滚执行
const rollbackExecution = async () => {
  try {
    await ElMessageBox.confirm(
      '确定要回滚这次执行吗？此操作不可撤销。',
      '确认回滚',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )

    actionLoading.rollback = true
    const response = await executionApi.rollbackExecution(executionId.value)

    if (response.data?.code === 200) {
      ElMessage.success('回滚任务已提交')
      refreshDetail()
    } else {
      ElMessage.error(response.data?.message || '回滚失败')
    }
  } catch (error) {
    if (error !== 'cancel') {
      console.error('回滚失败:', error)
      ElMessage.error('回滚失败')
    }
  } finally {
    actionLoading.rollback = false
  }
}

// 验证执行结果
const verifyExecution = async () => {
  try {
    actionLoading.verify = true
    const response = await executionApi.verifyExecution(executionId.value)
    ElMessage.success('验证任务已提交')
    refreshDetail()
  } catch (error) {
    console.error('验证失败:', error)
    ElMessage.error('验证失败')
  } finally {
    actionLoading.verify = false
  }
}

// 导出日志
const exportLogs = async () => {
  try {
    const response = await executionApi.exportExecutionLogs(executionId.value, {
      format: 'json',
      level: logFilter.level || undefined
    })

    // 创建下载链接
    const blob = new Blob([JSON.stringify(response.data, null, 2)], {
      type: 'application/json'
    })
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = `execution_${executionId.value}_logs.json`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)

    ElMessage.success('日志导出成功')
  } catch (error) {
    console.error('导出日志失败:', error)
    ElMessage.error('导出日志失败')
  }
}

// 计算统计数据
const getSuccessCount = () => {
  if (!executionDetail.value?.target_results) return 0
  return executionDetail.value.target_results.filter(r => r.status === 'success').length
}

const getFailureCount = () => {
  if (!executionDetail.value?.target_results) return 0
  return executionDetail.value.target_results.filter(r => r.status === 'failure').length
}

const getTotalCount = () => {
  return executionDetail.value?.target_results?.length || 0
}

const getVerificationSuccessCount = () => {
  if (!executionDetail.value?.verification_results) return 0
  return executionDetail.value.verification_results.filter(r => r.status === 'success').length
}

const getVerificationFailureCount = () => {
  if (!executionDetail.value?.verification_results) return 0
  return executionDetail.value.verification_results.filter(r => r.status === 'failure').length
}

// 获取状态类型
const getStatusType = (status) => {
  const typeMap = {
    success: 'success',
    running: 'warning',
    failed: 'danger',
    pending: 'info',
    partial_failure: 'warning'
  }
  return typeMap[status] || 'info'
}

// 获取状态文本
const getStatusText = (status) => {
  const textMap = {
    success: '成功',
    running: '运行中',
    failed: '失败',
    pending: '等待中',
    partial_failure: '部分失败'
  }
  return textMap[status] || status
}

// 获取触发类型文本
const getTriggerTypeText = (type) => {
  const textMap = {
    manual: '手动执行',
    scheduled: '定时执行',
    trigger: '触发执行',
    system: '系统执行'
  }
  return textMap[type] || type
}

// 获取日志级别类型
const getLogLevelType = (level) => {
  const typeMap = {
    info: 'info',
    warning: 'warning',
    error: 'danger',
    debug: 'success'
  }
  return typeMap[level] || 'info'
}

// 格式化日期时间
const formatDateTime = (dateTime) => {
  if (!dateTime) return '-'
  return new Date(dateTime).toLocaleString('zh-CN')
}

// 格式化时长
const formatDuration = (seconds) => {
  if (!seconds) return '-'
  if (seconds < 60) return `${seconds}秒`
  const minutes = Math.floor(seconds / 60)
  const remainingSeconds = seconds % 60
  return `${minutes}分${remainingSeconds}秒`
}

// 页面加载时获取数据
onMounted(() => {
  fetchExecutionDetail()
  fetchLogs()
})
</script>

<style scoped>
.execution-detail-page {
  padding: 0;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.header-actions {
  display: flex;
  gap: 12px;
}

.status-overview {
  margin-bottom: 20px;
}

.status-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.status-header h3 {
  margin: 0;
  color: #303133;
}

.error-message {
  margin-top: 20px;
}

.action-card {
  margin-bottom: 20px;
}

.action-buttons {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.results-card,
.verification-card,
.logs-card {
  margin-bottom: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.log-filters {
  display: flex;
  gap: 8px;
  align-items: center;
}

.logs-container {
  max-height: 600px;
  overflow-y: auto;
  border: 1px solid #e6e6e6;
  border-radius: 4px;
}

.log-item {
  border-bottom: 1px solid #f0f0f0;
  padding: 12px;
}

.log-item:last-child {
  border-bottom: none;
}

.log-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 8px;
}

.log-time {
  font-size: 12px;
  color: #909399;
}

.log-step {
  font-size: 12px;
  color: #606266;
  background-color: #f4f4f5;
  padding: 2px 6px;
  border-radius: 2px;
}

.log-message {
  color: #303133;
  line-height: 1.5;
  margin-bottom: 8px;
}

.log-details {
  font-size: 12px;
}

.log-details pre {
  background-color: #f5f7fa;
  padding: 8px;
  border-radius: 4px;
  overflow-x: auto;
  max-height: 200px;
}

.log-error {
  border-left: 3px solid #f56c6c;
  background-color: #fef0f0;
}

.log-warning {
  border-left: 3px solid #e6a23c;
  background-color: #fdf6ec;
}

.log-info {
  border-left: 3px solid #409eff;
  background-color: #ecf5ff;
}

.empty-logs {
  text-align: center;
  padding: 40px;
  color: #909399;
}

.logs-pagination {
  margin-top: 20px;
  text-align: center;
}

.empty-state {
  text-align: center;
  padding: 60px 20px;
  color: #909399;
}

.empty-state .icon {
  margin-bottom: 16px;
}

.loading-container {
  padding: 20px;
}
</style>
